/*
 * @Author: 0x9DEFA478
 * @Date: 2024-02-03 14:49:47
 * @LastEditTime: 2024-02-23 23:51:52
 * @LastEditors: 0x9DEFA478
 * @Description: 
 * QQ:2652450237
 * ============================================================================================================================================
 * 
 * 
 * 
 *                                                                                               ************      ****************************
 *                                                                                             ************      ****************************  
 *                                                                                           ************      ****************************    
 *                                                                                         ************      ****************************      
 *                                                                                       ************      ************                        
 *                                                                                     ************      ************                          
 *                                                                                   ************      ************                            
 *                                                                                 ************      ************                              
 *                                                                               ************      ************                                
 *                                                                             ************      ************                                  
 *                                                                           ************      ************                                    
 *                                                                         ************      ************                                      
 *                                                                       ************      ************                                        
 *                                                                     ************      ************                                          
 *                                                                   ************      ************                                            
 *                                                                 ************      ************                                              
 *                                                               ************      ************                                                
 *                                                             ************      ************                                                  
 *                                                           ************      ************                                                    
 *                                                         ************      ************                                                      
 *                                                       ************      ************                                                        
 *                                                     ************      ************                                                          
 *                                                   ************      ************                                                            
 *                                                 ************      ************                                                              
 *                                               ************      ************                                                                
 *                                             ************      ************                                                                  
 *                                           ************      ************                                                                    
 *                                         ************      ************                                                                      
 *                                       ************      ************                                                                        
 *                                     ************      ************                                                                          
 *                                   ************      ************                                                                            
 *                                 ************      ************                                                                              
 *                               ************      ************                                                                                
 *                             ************      ************                                                                                  
 *                           ************      ************                                                                                    
 *                         ************      ************                                                                                      
 *       ****************************      ************                                                                                        
 *     ****************************      ************                                                                                          
 *   ****************************      ************                                                                                            
 * ****************************      ************                                                                                              
 * 
 * 
 * 
 * ============================================================================================================================================
 * 
 */
#ifndef hH_Thread_HPP_
#define hH_Thread_HPP_
#include "H_Invoke.hpp"
#include "H_Type.hpp"
#include <string>




namespace H{

  class Thread_LL_Abstract{
    public:
      Thread_LL_Abstract(DelegateInvokeAbstract* invoke):invoke(invoke){}
      virtual ~Thread_LL_Abstract(){}
      virtual void Start()=0;
      virtual void Start(size StackSize,size Priority,const char* ThreadName)=0;
      virtual void Join()=0;
      virtual bool Detach()=0;
    protected:
      DelegateInvokeAbstract* invoke;
  };
#if __cplusplus >= 202000L
  template<class T>
  concept is_Thread_LL=requires(T& t,DelegateInvokeAbstract* invoke){
    t.Start();
    T(invoke);
  };
#endif

#if __cplusplus >= 202000L
  template<is_Thread_LL Thread_LL>
#else
  template<class Thread_LL>
#endif
  class Thread{

    public:
      Thread():ll(nullptr),invoke(nullptr){}
      template<typename T_Invoke,typename... T_Args>
      Thread(T_Invoke&& invoke,T_Args&&... args){
        Construction(static_cast<T_Invoke&&>(invoke),static_cast<T_Args&&>(args)...);
      }
      ~Thread(){
        if(ll!=nullptr){
          delete ll;
        }
        if(invoke!=nullptr){
          delete invoke;
        }
      }

      Thread(const Thread& thread){
        this->ll=ll;
        this->invoke=invoke;
        this->ThreadName=ThreadName;
        ll=nullptr;
        invoke=nullptr;
      }

      void Start(){
        if(ll!=nullptr){
          ll->Start();
        }
      };

      void Start(size StackSize,size Priority,const std::string& ThreadName){
        if(ll!=nullptr){
          this->ThreadName=ThreadName;
          ll->Start(StackSize,Priority,this->ThreadName.c_str());
        }
      }

      void Join(){
        if(ll!=nullptr){
          ll->Join();
        }
      };

      void Detach(){
        if(ll!=nullptr){
          if(ll->Detach()){
            ll=nullptr;
            invoke=nullptr;
          }
        }
      }
    
    private:
      template<typename T_Invoke,typename... T_Args>
      void Construction(T_Invoke&& invoke,T_Args&&... args){
#if __cplusplus >= 201700L
        this->invoke=new DelegateInvoke(static_cast<T_Invoke&&>(invoke),static_cast<T_Args&&>(args)...);
#else
        this->invoke=new DelegateInvoke<T_Invoke,T_Args...>(static_cast<T_Invoke&&>(invoke),static_cast<T_Args&&>(args)...);
#endif
        this->ll=new Thread_LL(this->invoke);
      }

    private:
      Thread_LL_Abstract* ll;
      DelegateInvokeAbstract* invoke;
      std::string ThreadName;
  };

}

#if __cplusplus >= 202000L
#define H_is_Thread_LL H::is_Thread_LL
#else
#define H_is_Thread_LL class
#endif




#endif //hH_Thread_HPP_
